#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <memory>

// -------------------- User 类 --------------------

// 用户类，包含用户名称和权限列表
class User {
private:
    std::string name;
    std::vector<std::string> permissions;

public:
    // 构造函数，初始化用户名称和权限
    User(const std::string& userName, const std::vector<std::string>& perms)
        : name(userName), permissions(perms) {}

    // 检查用户是否拥有指定权限
    bool hasPermission(const std::string& permission) const {
        return std::find(permissions.begin(), permissions.end(), permission) != permissions.end();
    }

    // 获取用户名称
    std::string getName() const { return name; }
};

// -------------------- Document 类 --------------------

// 文档类，提供显示文档内容的方法
class Document {
public:
    void displayDocument() const {
        std::cout << "Displaying document content." << std::endl;
    }
};

// -------------------- DocumentAccessProxy 类 --------------------

// 文档访问代理类，控制对 Document 对象的访问
class DocumentAccessProxy {
private:
    std::shared_ptr<Document> document; // 使用智能指针管理 Document 对象
    std::shared_ptr<User> user;

public:
    // 构造函数，初始化 Document 和 User 对象
    DocumentAccessProxy(std::shared_ptr<Document> doc, std::shared_ptr<User> usr)
        : document(doc), user(usr) {}

    // 显示文档内容，前提是用户拥有 "READ" 权限
    void displayDocument() {
        if (user->hasPermission("READ")) {
            std::cout << user->getName() << " has READ permission. Access granted." << std::endl;
            document->displayDocument();
        } else {
            std::cout << user->getName() << " does NOT have READ permission. Access denied." << std::endl;
        }
    }
};

// -------------------- 测试用例 --------------------

int main() {
    // 创建一个文档对象
    std::shared_ptr<Document> doc = std::make_shared<Document>();

    // 创建两个用户，一个有 READ 权限，一个没有
    std::shared_ptr<User> userWithRead = std::make_shared<User>("Alice", std::vector<std::string>{"READ", "WRITE"});
    std::shared_ptr<User> userWithoutRead = std::make_shared<User>("Bob", std::vector<std::string>{"WRITE"});

    // 创建文档访问代理对象
    DocumentAccessProxy proxyWithRead(doc, userWithRead);
    DocumentAccessProxy proxyWithoutRead(doc, userWithoutRead);

    // 尝试通过代理显示文档
    std::cout << "---- Attempting to display document with user who has READ permission ----" << std::endl;
    proxyWithRead.displayDocument();

    std::cout << "\n---- Attempting to display document with user who does NOT have READ permission ----" << std::endl;
    proxyWithoutRead.displayDocument();

    return 0;
}
